#ifndef FemDrawer_H
#define FemDrawer_H


#include <ctime>
#include "PArray.h"
#include "Vector.h"
#include "TopologicalObject.h"
#include "Ray.h"

#include "SweepDescription.h"
#include "Trackball.h"

class CutPerformer;

#define DECLARE_TOGGLE_FUNCTION(x,y) bool x ## _b_; void Toggle## y ();

class DragState {
public:
	Vector3 scale_;
	Vector3 translate_;
	Quaternion quat_;

	DragState ();
};

class FEMDrawer
{
public:
	CutPerformer	*cut_performer_;
	FiniteElementModel	*fem_;
	TopologicalObject	* marked_;
	Node * marked_node_;

	DragState view_drag_, light_drag_, force_drag_,  cut_drag_;

	// normal smoothing:
	Array<Vector3> surface_normals_;
	Array<int> vertex_counts_;

	SweepDescription last_sweep_; // sweep used for the last dissect
	SweepDescription this_sweep_; // sweep used for the currently show faces. 
	Ray	selection_ray_;

	Real distance_;
	Real intersect_dist_;
	Real force_factor_;



	Real velocity_; 

	int stereo_direction_;
	int click_x_; 
	int click_y_;
	int frame_i_;

	time_t	start_time_;

	LinkArray<Triangle> face_arr_;

	Array<Simplex> edge_array_;

	void UpdateFaces ();
	void DrawFrame ();
	void DrawFeature ();
	void DrawSelector ();
	void DrawScalpel ();  
	void FixObject (bool);
	void FocusOnModel ();

	FEMDrawer (FiniteElementModel*);
	~FEMDrawer ();

	void RotateDrag (Quaternion*,int, int, int, int, int, int);
	void TranslateDrag (Vector3*,int, int, int, int, int, int);
	void ScaleDrag (Vector3*,int, int, int, int, int, int);
	void EnterVertex (Vector3);
	void ComputeNormals ();
	void SetMarked (TopologicalObject*, Node*);
	void SetMaterial ();
	void SetLighting ();
	void SetColor (float*);

	void SetAntiAlias();
	void SetScalpel ();
	void SetCamera (int lr = 0);
	void Rotate (Real incr);
	void Movement (Vector3 );
	void AdjustForce (Vector3);
	void DrawNode (Node*);
	void SetDepthCue ();
	void Setup ();
	void EndRotateDrag (Quaternion*);
	void SetSelector ();
	void DrawTriangle (Triangle*t,bool);
	void Draw ();
	void SetFrustrum ();
	void SetExtraRotation (Real,Real);
	void FixNode (Node*,bool);
	void ShowCut ();
	void NextCut ();
	void StopCut ();
	
	bool show_back_b_;
	bool fog_b_;
	bool edge_b_;
	bool inside_b_;
	bool lighting_b_;
	bool tet_quality_b_;
	bool smooth_b_;
	bool normal_b_;
	bool relaxation_b_;
	bool surface_selector_b_;
	bool solid_b_;
	bool original_b_;
	bool force_display_b_;

	void ToggleFog();
	void ToggleEdge();
	void ToggleSetEdge();
	void ToggleInside();
	void ToggleShowBack();
	void ToggleLighting();
	void ToggleForceDisplay();
	void ToggleTetQuality();
	void ToggleSmooth();
	void ToggleNormal();
	void ToggleRelaxation();
	void ToggleSurfaceSelector();
	void ToggleSolid();
	void ToggleOriginal();
	void ToggleSetDepthCue();
	void ToggleSetLighting();

	void Zoom (Real);
	void Unfix ();
	void Fix ();
	void PrintMarked();
	char * Stats();

	Vector3 PendingScalpelVelocity ();
};



#endif /* FemDrawer_H */

